package com.qijian.flowable.util;

import com.qijian.common.utils.StringUtils;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl;
import org.flowable.engine.impl.util.CommandContextUtil;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 表达式
 */
public class ExpressionCmd implements Command<Boolean>, Serializable {

    protected ProcessEngine processEngine;

    protected String processInstanceId;

    protected String exp;

    protected Map<String, Object> variableMap;

    public ExpressionCmd(String exp, Map<String, Object> variableMap) {
        this.exp = exp;
        this.variableMap = variableMap;
    }

    public ExpressionCmd(ProcessEngine processEngine, String processInstanceId, String exp, Map<String, Object> variableMap) {
        this.processEngine = processEngine;
        this.processInstanceId = processInstanceId;
        this.exp = exp;
        this.variableMap = variableMap;
    }

    @Override
    public Boolean execute(CommandContext commandContext) {
        //表达式为空时，直接返回true
        if (StringUtils.isBlank(this.exp)) {
            return Boolean.TRUE;
        }
        Map<String, Object> variables = new HashMap<>(this.variableMap);
        Expression expression =  CommandContextUtil.getProcessEngineConfiguration().getExpressionManager().createExpression(this.exp);

        //流程实例id不为空
        if (StringUtils.isNotBlank(this.processInstanceId)) {
            RuntimeService runtimeService = this.processEngine.getRuntimeService();
            ExecutionEntity processExecutionEntity = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(this.processInstanceId).includeProcessVariables().singleResult();
            if (null != processExecutionEntity) {
                //流程实例参数
                Map<String, Object> processVariables = processExecutionEntity.getVariables();
                if (null != processVariables) {
                    processVariables.putAll(this.variableMap);

                    variables = processVariables;
                }
            }
        }

        ExecutionEntity executionEntity = new ExecutionEntityImpl();
        executionEntity.setVariables(variables);

        Object value = expression.getValue(executionEntity);
        return value != null && "true".equals(value.toString());
    }

}
